﻿#include "QCefRenderProcessHandler.h"

//单一进程模式
#ifdef QT_CEF_SINGLE_PROCESS
#include "QCefBrowserApp.h"
#else
#include "QCefRenderApp.h"
#endif // QT_CEF_SINGLE_PROCESS


QCefRenderProcessHandler::QCefRenderProcessHandler()
    : m_lastNodeIsEditable(false)
{
    QCEF_DEBUG();
}

QCefRenderProcessHandler::~QCefRenderProcessHandler()
{
    QCEF_DEBUG();

    m_renderClients.clear();
}


//////////////////////////////////////////////////////////////////////////
//CefRenderProcessHandler
void QCefRenderProcessHandler::OnWebKitInitialized()
{
    QCEF_DEBUG();

    //
}

void QCefRenderProcessHandler::OnBrowserCreated(CefRefPtr<CefBrowser> browser,
                                     CefRefPtr<CefDictionaryValue> extra_info)
{
    QCEF_DEBUG();

    //
}

void QCefRenderProcessHandler::OnBrowserDestroyed(CefRefPtr<CefBrowser> browser)
{
    QCEF_DEBUG();

    //
}

CefRefPtr<CefLoadHandler> QCefRenderProcessHandler::GetLoadHandler()
{
    QCEF_DEBUG();

    return nullptr;
}

void QCefRenderProcessHandler::OnContextCreated(CefRefPtr<CefBrowser> browser,
                                     CefRefPtr<CefFrame> frame,
                                     CefRefPtr<CefV8Context> context)
{
    QCEF_DEBUG();

    //
    if (frame != nullptr)
    {
        int64 frameId = frame->GetIdentifier();
        if (m_renderClients.find(frameId) == m_renderClients.end())
        {            
        #ifdef QT_CEF_SINGLE_PROCESS
            CefRefPtr<QCefRenderClient> client = new QCefRenderClient(QCefBrowserApp::instance());
        #else
            CefRefPtr<QCefRenderClient> client = new QCefRenderClient(QCefRenderApp::instance());
        #endif // QT_CEF_SINGLE_PROCESS

            client->init(browser, frame, context);

            m_renderClients[frameId] = client;
        }
    }
}

void QCefRenderProcessHandler::OnContextReleased(CefRefPtr<CefBrowser> browser,
                                      CefRefPtr<CefFrame> frame,
                                      CefRefPtr<CefV8Context> context)
{
    QCEF_DEBUG();

    //
    if (frame != nullptr)
    {
        int64 frameId = frame->GetIdentifier();
        ClientMap::iterator it = m_renderClients.find(frameId);
        if (it != m_renderClients.end())
        {
            m_renderClients.erase(it);
        }
    }
}

void QCefRenderProcessHandler::OnUncaughtException(CefRefPtr<CefBrowser> browser,
                                        CefRefPtr<CefFrame> frame,
                                        CefRefPtr<CefV8Context> context,
                                        CefRefPtr<CefV8Exception> exception,
                                        CefRefPtr<CefV8StackTrace> stackTrace)
{
    QCEF_DEBUG();

    //
}

void QCefRenderProcessHandler::OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
                                         CefRefPtr<CefFrame> frame,
                                         CefRefPtr<CefDOMNode> node)
{
    QCEF_DEBUG();

    if (frame != nullptr && node != nullptr)
    {
        //
        bool isEditable = node->IsEditable();
        if (isEditable != m_lastNodeIsEditable)
        {
            // Notify the browser of the change in focused element type.
            m_lastNodeIsEditable = isEditable;
            CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create(kCefViewClientRenderFocusedNodeChangedMessage);
            message->GetArgumentList()->SetBool(0, isEditable);
            frame->SendProcessMessage(PID_BROWSER, message);
        }
    }
}

bool QCefRenderProcessHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
                                             CefRefPtr<CefFrame> frame,
                                             CefProcessId source_process,
                                             CefRefPtr<CefProcessMessage> message)
{
    QCEF_DEBUG();

    return false;
}


